require 'forwardable'

module Gamifier
  module DSL
    class Network
      extend Forwardable
      def_delegator :Gamifier, :engine, :engine

      attr_reader :source
      attr_reader :sites
      attr_reader :api_keys

      def initialize(*args)
        @source         = ::Gamifier::Network.new(*args)
        @sites          = []
        @api_keys       = []
      end

      def engine
        @engine ||= Gamifier::Engine.new(:key => get_key('private') || Gamifier.config[:key])
      end

      def enterprise_engine
        raise ArgumentError, "You must specify an enterprise key" unless Gamifier.config[:enterprise_key]
        @enterprise_engine ||= Gamifier::Engine.new(:key => Gamifier.config[:enterprise_key])
      end

      def site(name, &block)
        new_site = DSL::Site.new(:name => name)
        @sites.push(new_site)

        DSL.eval_with_context(new_site, &block)
      end

      def api_key(&block)
        new_key = DSL::ApiKey.new
        new_key.source.engine = enterprise_engine
        @api_keys.push(new_key)

        DSL.eval_with_context(new_key, &block)
      end

      def save_network!
        begin
          if self.save
            save_api_keys!
          end
        rescue
          Gamifier.logger.debug "Can't save #{self}"
        end
      end

      def save_api_keys!
        api_keys.each do |key|
          key.engine = enterprise_engine
          key.network_id = self.id
          key.save
        end
      end

      def save_sites!
        sites.each do |site|
          if gsite = engine.sites.find(site.url)
            site._id = gsite._id
          end
          site.engine = engine
          site.save
        end
      end

      def get_key(access = 'private')
        key = self.api_keys.select {|k| k.access == access}.first
        return key.key if key
        nil
      end

      def save!
        save_sites!
      end

      def method_missing(*args, &block)
        source.send(*args, &block)
      end

    end
  end
end
